﻿//////////////////////////////////////////////////////////////////////
//                       Class MaxFilter                            //
//         Haalt een Max filter van 3x3 over de InputImage          //
//                                                                  //
//                          Made By:                                //
//                      Hessel Meulenbeld                           //
//                                                                  //
//                          Version:                                //
//                1.0 - Hessel Meulenbeld - 16-03-2012              //
//                                                                  //
//////////////////////////////////////////////////////////////////////
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.Collections;

namespace THO7AlgoritmTimerApplication {
    class MaxFilter : VisionAlgorithm {
        String filter = "";
        public MaxFilter(String name, String f) : base(name) { filter = f; }
        public override System.Drawing.Bitmap DoAlgorithm(System.Drawing.Bitmap sourceImage) {
            Bitmap dest = new Bitmap(sourceImage.Width, sourceImage.Height);
            BitmapData bmpdata = sourceImage.LockBits(new Rectangle(0, 0, sourceImage.Width, sourceImage.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
            BitmapData bmpdata1 = dest.LockBits(new Rectangle(0, 0, sourceImage.Width, sourceImage.Height), ImageLockMode.WriteOnly, PixelFormat.Format24bppRgb);
            IntPtr ptr = bmpdata.Scan0;
            IntPtr ptr1 = bmpdata1.Scan0;
            int regellengte = Math.Abs(bmpdata.Stride);
            int bytes = regellengte * sourceImage.Height;
            byte[] rgbValues = new byte[bytes];
            byte[] output = new byte[bytes];
            System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes);
            System.Runtime.InteropServices.Marshal.Copy(ptr, output, 0, bytes);

            for (int hoogte = 0; hoogte < sourceImage.Height; hoogte++) {
                for (int breedte = 0; breedte < regellengte; breedte += 3) {
                    int pixel = (hoogte * regellengte) + breedte;
                    byte kleur = (byte)((rgbValues[pixel] + rgbValues[pixel + 1] + rgbValues[pixel + 2]) / 3);
                    rgbValues[pixel] = (kleur);
                    rgbValues[++pixel] = (kleur);
                    rgbValues[++pixel] = (kleur);
                }
            }
            byte waarde = 0;
            for (int regelnummer = 0; regelnummer < sourceImage.Height - ((3 / 2) + 1) * 2; regelnummer++) {
                for (int convolutie = 0; convolutie < regellengte - ((3 / 2) + 1) * 6; convolutie += 3) {
                    int begin_pixel = ((regelnummer * regellengte) + convolutie);
                    byte[] cumu_hist = new byte[256];
                    for (int hoogte = 0; hoogte < 3; hoogte++) {
                        for (int breedte = 0; breedte < 3; breedte++) {
                            int pixel = begin_pixel + (hoogte * regellengte) + (breedte * 3);
                            cumu_hist[rgbValues[pixel]]++;
                        }
                    }
                    switch (filter) {
                        case "Max":
                            for (byte i = 0; i <= 255; i++) {
                                if (cumu_hist[i] > 0) {
                                    waarde = i;
                                    break;
                                }
                            }
                            break;
                        case "Min":
                            for (byte i = 255; i >= 0; i--) {
                                if (cumu_hist[i] > 0) {
                                    waarde = i;
                                    break;
                                }
                            }
                            break;
                    }
                    output[begin_pixel] = (waarde);
                    output[begin_pixel + 1] = (waarde);
                    output[begin_pixel + 2] = (waarde);
                }
            }
            System.Runtime.InteropServices.Marshal.Copy(output, 0, ptr1, bytes);
            sourceImage.UnlockBits(bmpdata);
            dest.UnlockBits(bmpdata1);
            return dest;
        }
    }
}
